﻿using System;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using CommandLine;
using CommandLine.Text;
using MediaSage.Lib.UIFramework.DataFile;

namespace BuildThemePackage
{
    internal class Program
    {
        private static string DLLName;
        private static string ThemeName;
        private static int MajorVer;
        private static int MinorVer;
        private static int BuildNum;
        private static bool Default = false;
        private static string[] Capabilities;
        private static string UpdateURL;
        private static string ResourceDir;

        private static void Main(string[] args)
        {
            Console.WriteLine("Creating Theme Package:");
            Console.WriteLine(" - Checking CLI Args");
            ProcessCLI(args);
            Console.WriteLine(" - Testing package contents");
            if (!File.Exists(DLLName))
            {
                Console.WriteLine(" " + DLLName + " not found, aborting");
                Environment.Exit(1);
            }
            if (!Directory.Exists(ResourceDir))
            {
                Console.WriteLine(" Directory: " + ResourceDir + " not found, aborting");
                Environment.Exit(1);
            }
            Console.WriteLine(" - Getting Theme Version");
            ThemeData dataFile = new ThemeData();
            Assembly theme = null;
            try
            {
                theme = Assembly.LoadFrom(DLLName);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception loading Theme: " + e.Message);
                Environment.Exit(1);
            }
            if (theme == null)
            {
                Console.WriteLine("Theme incorrectly loaded, exiting");
                Environment.Exit(1);
            }
            Version version = theme.GetName().Version;
            dataFile.Version.Major = version.Major;
            dataFile.Version.Minor = version.Minor;
            dataFile.Version.BuildNumber = version.Build;
            dataFile.DLL = Path.GetFileName(DLLName);
            string[] tmp = ResourceDir.Split(Path.DirectorySeparatorChar);
            int a = tmp.Length;
            while (tmp[a] = String.IsNullOrEmpty() && a > 0)
            {
                a--;
            }
            dataFile.ResourceDirectory = tmp[a];
            dataFile.Capabilitiy = Capabilities;
            dataFile.Default = Default;

            XmlSerializer serializer = new XmlSerializer(dataFile.GetType());

            string tempDir = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());

            Console.WriteLine(" - Creating Temporary Dir: " + tempDir);
            try
            {
                Directory.CreateDirectory(tempDir);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception creating Temporary Dir, msg: " + e.Message);
                Environment.Exit(1);
            }

            Console.WriteLine(" - Serializing XML File");
            string xmlFilename = Path.Combine(tempDir, "THEME.XML");
            try
            {
                TextWriter tw = new StreamWriter(xmlFilename);
                serializer.Serialize(tw, dataFile);
                tw.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception serializing THEME.XML");
                Environment.Exit(1);
            }
            Console.WriteLine("- Copying files to temp location");
            try
            {
                Console.WriteLine("     - Copying " + DLLName);
                File.Copy(DLLName, Path.Combine(tempDir, dataFile.DLL));
                Directory.CreateDirectory(Path.Combine(tempDir, dataFile.ResourceDirectory));
                string resDir = Path.Combine(tempDir, dataFile.ResourceDirectory);
                string[] files = Directory.GetFiles(ResourceDir);
                foreach (string file in files)
                {
                    Console.WriteLine("     - Copying " + file);
                    File.Copy(Path.Combine(ResourceDir, file), Path.Combine(resDir, file));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception copying files: "+e.Message);
                Environment.Exit(1);
            }
        }

        private static void ProcessCLI(string[] args)
        {
            var options = new Options();
            var parser = new CommandLineParser(new CommandLineParserSettings(false, true, Console.Error));
            if (!parser.ParseArguments(args, options))
            {
                Environment.Exit(1);
            }
            DLLName = options.DLL;
            Capabilities=options.Capabilities;
            Default=options.Default;
            ThemeName=options.Name;
            UpdateURL = options.UpdateURL;
   
        }


        internal sealed class Options : CommandLineOptionsBase
        {
            #region Properties

            [Option("u", "updateurl", HelpText = "URL the Theme gets updates from")]
            public string UpdateURL { get; set; }

            [Option("d", "dll", Required = true, HelpText = "Theme main DLL")]
            public string DLL { get; set; }

            [Option("n", "name", Required = true, HelpText = "Theme name")]
            public string Name { get; set; }
            
            [Option("d","default", HelpText="Mark as default Theme")]
            public bool Default { get; set; }

            [OptionArray("c", "capability", HelpText = "Define capability of Theme")]
            public string[] Capabilities { get; set; }
            #endregion

            [Option("r", "resourceDirectory", HelpText = "The resource directory for the Theme")]
            public string ResourceDir { get; set; }

            [HelpOption]
            public string GetUsage()
            {
                var ht = new HelpText(new HeadingInfo("BuildThemePackage", "0.9"));
                string errors = ht.RenderParsingErrorsText(this, 2);
                // indent with two spaces
                if (!string.IsNullOrEmpty(errors))
                {
                    ht.AddPreOptionsLine(string.Concat(Environment.NewLine, "ERROR(S):"));
                    ht.AddPreOptionsLine(errors);
                }
                ht.AddOptions(this);
                return ht;
            }
        }
    }
}
